package jupiter.filters;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.json.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jupiter.message.*;
import jupiter.util.EventSubscriber;

public class Filter {
	
	static Logger logger = LoggerFactory.getLogger(Filter.class);
	/*
	 * This filters messages for pre-processing before they are sent to all other channels.
	 * If you want to avoid sending a message to all of jabbify channels, raise a 
	 * FilterException with the json response you still want to provide.
	 */
	public static JSONObject filter(Message m, boolean inboxPhase) throws FilterException, Throwable{
		JSONObject obj = m.json; //return the json right back
		try{
//			logger.info("! Filtering "+m.type()+":"+m.action());
			Class<?> c = Class.forName("jupiter.filters."+capitalize(m.type())+"Filter");
			Object t = c.newInstance();
			Method meth = c.getDeclaredMethod(m.action()+(inboxPhase ? "Inbox" :""), m.getClass());
			obj = (JSONObject) meth.invoke(t, m);
		}catch(ClassNotFoundException e){
			//logger.debug("Class not found: jupiter.filters."+capitalize(m.type)+"Filter", e);
			//throw new FilterException("{error: 'Can not process this type'}");
		} catch (InstantiationException e) {
			//logger.debug("InstantiationException", e);
			//throw new FilterException("{error: 'Can process this action'}");
		} catch (IllegalAccessException e) {
			//logger.debug("IllegalAccessException", e);
			//return null;
		} catch (SecurityException e) {
			//logger.debug("SecurityException", e);
			//return null;
		} catch (NoSuchMethodException e) {
			//logger.debug("NoSuchMethodException", e);
			//return null;
		} catch (IllegalArgumentException e) {
			//logger.debug("IllegalArgumentException", e);
			//return null;
		} catch (InvocationTargetException e) {
			//logger.debug("InvocationTargetException", e);
			throw e.getCause();
			//return null;
		} 
		 //send to everyone, error yourself if you don't want this to happen
		return obj;
	}
	public static String capitalize(String s) {
        if (s.length() == 0) return s;
        return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
    }
}
